package com.pengliu.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.pengliu.common.bean.OssFile;
import com.pengliu.common.bean.OssUser;
import com.pengliu.common.bean.OssUserExample;
import com.pengliu.common.exception.ServiceException;
import com.pengliu.config.BaseController;
import com.pengliu.service.HttpService;
import com.pengliu.service.OssFileService;
import com.pengliu.service.OssUserService;
import com.pengliu.util.Maps;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.Thumbnails.Builder;

@Controller
public class OssSignController extends BaseController{
	
	@Value("${host}")
	private String host;
	
	@Autowired
	private OssUserService ossUserService;
	
	@Autowired
	private OssFileService ossFileService;
	
	@Autowired
	private HttpService httpService;
	
    @ResponseBody
    @RequestMapping(value = "/getOssSign", method = RequestMethod.GET)
	public Map<String,Object> getOssSign(
		@RequestParam(name="bucket",defaultValue="/bucket_test") String bucket,
		@RequestParam(name="dir",defaultValue="/test") String dir
	) throws Exception{
    	
    	if(!bucket.substring(0,1).equals("/")) {
    		bucket = "/".concat(bucket);
    	}
    	if(!dir.substring(0,1).equals("/")) {
    		dir = "/".concat(dir);
    	}
    	
    	OssUser ossUser = null;
    	
    	//获取当前登陆用户
    	Integer currentSysUserId = getCurrentSysUser().getId();
    	if(null != currentSysUserId) {
    		OssUserExample ossUserExample = new OssUserExample();
    		ossUserExample.getCriteria()
    			.andSysUserIdEqualTo(currentSysUserId)
    			.andBucketEqualTo(bucket);
    		ossUser = ossUserService.selectOneByExample(ossUserExample);
    	}
    	
    	if(null == ossUser) {
    		throw new ServiceException("您无权上传文件,请创建目录空间");
    	}
    	
    	Map<String,String> data = Maps.newConcurrentHashMap();
    	data.put("accessId",ossUser.getAccessId());
    	data.put("accessKey",ossUser.getAccessKey());
    	data.put("bucket",bucket);
    	data.put("dir",dir);
    	String reslutJson = httpService.requestGet(host+"/oss/authOss", data);
    	
    	Map<String,Object> resultMap = JSON.parseObject(reslutJson, Map.class);
		return resultMap;
	}
    
    
    /**
     * user: pengliu
     * date: 2018年11月13日
     * desc: 获取文件操作
     * 	命名规则:		_200x300		获取按比例缩放后的尺寸
     * 				_n200x300		获取不按比例缩放后的尺寸
     * 				_b25			获取百分比缩放的比例(如参数获取到原图大小的25%)
     * 				_+90			获取顺时针旋转90度的图片(如参数是负数则逆时针旋转90度)
     * 				_img			获取默认图片的60%比例展示
     * 				_q80			获取图片质量的80%
     * 				_200kb			获取缩放后的具体图片大小
     * 
     * @author pengliu
     */
    private void getFile(HttpServletRequest request, HttpServletResponse response,String fileName) throws Exception {
    	response.setHeader(" Access-Control-Allow-Methods", "POST");
        response.setHeader(" Access-Control-Allow-Origin", "*");
        
		String ossFileName = fileName;
		
		if( StringUtils.isNotBlank(fileName) && fileName.contains("_")) {
			fileName = fileName.substring(0,fileName.indexOf("_"));
		}
    	
    	OssFile ossFile = ossFileService.selectByPrimaryKey(fileName);
    	if(null == ossFile) {
    		throw new ServiceException("未找到文件或图片");
    	}
    	
    	if(ossFile.getContentType().contains("image")) {
    		response.setContentType(ossFile.getContentType());
    		
    		File checkFile = new File(ossFile.getBucket()+ossFile.getDirPath()+ossFileName+ossFile.getFileSuffix());
        	if(checkFile.exists()) {
        		FileUtils.copyFile(checkFile, response.getOutputStream());
        	}else if(!new File(ossFile.getFilePath()).exists() || ossFile.getEnableState().intValue() == 0) {
            	InputStream in = getClass().getClassLoader().getResourceAsStream("static/oss/img/404_default.jpg");
    			StreamUtils.copy(in, response.getOutputStream());
        	}else {
        		int width = 0;					//指定缩放比例		宽
        		int height = 0;					//指定缩放比例		高
        		boolean keepAspectRatio = true;	//true:按比例缩放,false:不按比例缩放
        		double scale = 0;					//缩放比例
        		int rotate = 0;					//旋转角度
        		double quality = 0;				//图片质量
        		boolean defaultScale = false;	//是否默认展示图片
        		
        		if(Pattern.compile("_[0-9]*x[0-9]*").matcher(ossFileName).find()) {
        			Matcher matcher = Pattern.compile("_([0-9]*)x([0-9]*)").matcher(ossFileName).reset();
        			while (matcher.find()) {
        				width = Integer.valueOf(matcher.group(1)).intValue();
        				height = Integer.valueOf(matcher.group(2)).intValue();
        			}
        		}
        		if(Pattern.compile("_n[0-9]*x[0-9]*").matcher(ossFileName).find()) {
        			Matcher matcher = Pattern.compile("_n([0-9]*)x([0-9]*)").matcher(ossFileName).reset();
        			while (matcher.find()) {
        				width = Integer.valueOf(matcher.group(1)).intValue();
        				height = Integer.valueOf(matcher.group(2)).intValue();
        			}
        			keepAspectRatio = false;
        		}
        		if(Pattern.compile("_b[0-9]{1,2}").matcher(ossFileName).find()) {
        			Matcher matcher = Pattern.compile("_b([0-9]{1,2})").matcher(ossFileName).reset();
        			while (matcher.find()) {
        				scale = Double.valueOf(matcher.group(1))/100;
        			}
        		}
        		if(Pattern.compile("_[\\+|\\-]{1}[0-9]+").matcher(ossFileName).find()) {
        			Matcher matcher = Pattern.compile("_([\\+|\\-]{1}[0-9]+)").matcher(ossFileName).reset();
        			while (matcher.find()) {
        				rotate = Integer.valueOf(matcher.group(1)).intValue();
        			}
        		}
        		if(Pattern.compile("_q[0-9]{1,2}").matcher(ossFileName).find()) {
        			Matcher matcher = Pattern.compile("_q([0-9]{1,2})").matcher(ossFileName).reset();
        			while (matcher.find()) {
        				quality = Double.valueOf(matcher.group(1))/100;
        			}
        		}
        		if(Pattern.compile("_img").matcher(ossFileName).find()) {
        			defaultScale = true;
        		}
        		
        		//源文件
        		File originalFile = new File(ossFile.getFilePath());
        		
            	Builder<File> fileBuilder = Thumbnails.of(originalFile);
            	
            	if(width > 0 && height > 0) {		//指定缩放
            		fileBuilder.size(width, height);
            	}
            	if(width > 0 && height > 0 && keepAspectRatio == false) {				//是否比例缩放
            		fileBuilder.keepAspectRatio(keepAspectRatio);
            	}
            	if(scale != 0) {						//比例缩放
            		fileBuilder.scale(scale);
            	}
            	if(rotate != 0) {					//旋转图片
            		fileBuilder.rotate(rotate);
            	}
            	if(quality != 0) {					//图片质量设置
            		fileBuilder.outputQuality(quality);
            	}
            	if(defaultScale) {					//默认展示原图的80%比例 并且质量是原图的40%
            		BufferedImage sourceImg =ImageIO.read(originalFile);
            		int sourceWidth = sourceImg.getWidth();
            		int sourceHeight = sourceImg.getHeight();
            		double length = (double)originalFile.length()/1024;
            		double sourceQuality = 0; 
            		if(sourceWidth>1000 || sourceHeight > 1000) {
            			sourceWidth *= 0.4;
            			sourceHeight *= 0.4;
            		}else if(sourceWidth>800 || sourceHeight > 800) {
            			sourceWidth *= 0.5;
            			sourceHeight *= 0.5;
            		}else if(sourceWidth>600 || sourceHeight > 600) {
            			sourceWidth *= 0.6;
            			sourceHeight *= 0.6;
            		}else if(sourceWidth>400 || sourceHeight > 400) {
            			sourceWidth *= 0.7;
            			sourceHeight *= 0.7;
            		}else if(sourceWidth>300 || sourceHeight > 300) {
            			sourceWidth *= 0.8;
            			sourceHeight *= 0.8;
            		}else if(sourceWidth>200 || sourceHeight > 200) {
            			sourceWidth *= 0.9;
            			sourceHeight *= 0.9;
            		}else {
            			sourceWidth *= 1;
            			sourceHeight *= 1;
            		}
            		
            		if(length>1024) { sourceQuality = 0.4; }
            		else if(length>800) { sourceQuality = 0.5; }
            		else if(length>600) { sourceQuality = 0.6; }
            		else if(length>500) { sourceQuality = 0.7; }
            		else if(length>400) { sourceQuality = 0.8; }
            		else if(length>300) { sourceQuality = 0.9; }
            		else { sourceQuality = 1; }
            		
            		fileBuilder.size(sourceWidth, sourceHeight);
            		fileBuilder.outputQuality(sourceQuality);
            	}
            	
            	
            	try {
            		fileBuilder.scale(1);
				} catch (Exception e) {
				}
            	
            	
            	fileBuilder.toFile(ossFile.getBucket()+ossFile.getDirPath()+ossFileName+ossFile.getFileSuffix());
            	
            	fileBuilder.toOutputStream(response.getOutputStream());
        	}
    		
    	}else if (ossFile.getContentType().contains("audio")) {
    		String accept = request.getHeader("Accept");
    		if(null != accept && accept.contains("image/*")) {
    			InputStream in = getClass().getClassLoader().getResourceAsStream("static/oss/img/yinyue.jpg");
    			StreamUtils.copy(in, response.getOutputStream());
    		}else {
        		try {
        			response.setContentType(ossFile.getContentType());
            		FileUtils.copyFile(new File(ossFile.getFilePath()), response.getOutputStream());
				} catch (Exception e) {
				}
    		}
    	}else if (ossFile.getContentType().contains("video")) {
    		String accept = request.getHeader("Accept");
    		if(null != accept && accept.contains("image/*")) {
            	InputStream in = getClass().getClassLoader().getResourceAsStream("static/oss/img/shipin.jpg");
    			StreamUtils.copy(in, response.getOutputStream());
    		}else {
    			try {
    				File file = new File(ossFile.getFilePath());
    				InputStream in = new FileInputStream(file);
    				response.setContentType(ossFile.getContentType());
            		StreamUtils.copy(in, response.getOutputStream());
				} catch (Exception e) {
				}
    		}
    	}else if (ossFile.getContentType().contains("text")) {
    		String accept = request.getHeader("Accept");
    		if(null != accept && accept.contains("text/plain")) {
            	InputStream in = getClass().getClassLoader().getResourceAsStream("static/oss/img/text.jpg");
    			StreamUtils.copy(in, response.getOutputStream());
    		}else {
    			try {
    				File file = new File(ossFile.getFilePath());
    				InputStream in = new FileInputStream(file);
    				response.setContentType(ossFile.getContentType());
            		StreamUtils.copy(in, response.getOutputStream());
				} catch (Exception e) {
				}
    		}
    	}else {
    		downloadFile(request, response, ossFile);
    	}
    }
    
    /**
     * user: pengliu
     * date: 2018年11月19日
     * desc: 下载文件
     */
    private void downloadFile(HttpServletRequest request, HttpServletResponse response,OssFile ossFile) throws IOException {
    	String accept = request.getHeader("Accept");
		if(null != accept && accept.contains("image/*")) {
            InputStream in = getClass().getClassLoader().getResourceAsStream("static/oss/img/wenjian.jpg");
			StreamUtils.copy(in, response.getOutputStream());
		}else {
			String fileName = ossFile.getFileTag();
    		// 中文文件名支持
    		String encodedfileName = null;
    		String agent = request.getHeader("USER-AGENT");
    		if (null != agent){
    			if (-1 != agent.indexOf("Firefox")) {//Firefox
    				encodedfileName = "=?UTF-8?B?" + (new String(Base64.encode(fileName.getBytes("UTF-8"))))+ "?=";
    			}else if (-1 != agent.indexOf("Chrome")) {//Chrome
    				encodedfileName = new String(fileName.getBytes(), "ISO8859-1");
    			} else {//IE7+ 包括edge
    				encodedfileName = java.net.URLEncoder.encode(fileName, "UTF-8");
    				encodedfileName = encodedfileName.replaceAll("\\+","%20");// 替换空格
    			}
    		} else {
    			encodedfileName = fileName;
    		}
    		File file = new File(ossFile.getFilePath());
    		response.setContentType(ossFile.getContentType());
    		response.setHeader("Content-Length", String.valueOf(file.length()));
    		response.setHeader("Content-Disposition", "attachment; filename=\"" + encodedfileName + "\"");
    		FileInputStream in = new FileInputStream(file);
    		StreamUtils.copy(in, response.getOutputStream());
		}
    }
    
    @CrossOrigin
    @RequestMapping("/ossGet/**/{fileName}")
    public void getFile0(HttpServletRequest request, HttpServletResponse response,@PathVariable String fileName) throws Exception {
    	getFile(request, response, fileName);
    }
}
